angular.module('chat.directives', [])

    .directive('lastMessage', function () {
        var directive = {};
        directive.restrict = 'E';
        directive.scope = {
            messages: "=",
            users: "=",
            selfId: "@",
            chatId: "=",
            currentChatId: "=",
            checkpoint: "=",
        };
        directive.template = '<div class="meta__sub--dark"></div>';
        directive.link = function (scope, element, attrs) {
            scope.$watchCollection('messages', messageListener);
            scope.$on('clearState', function (e, args) {
                if (e.currentScope.chatId == args.chat_id) {
                    clearUnreadMessageState(element.children("div"));
                }
            });

            function messageListener(newModel, oldModel, scope) {
                var messages = newModel;
                var users = scope.users;
                var selfId = scope.selfId;
                var chatId = scope.chatId;
                var currentChatId = scope.currentChatId;

                var maxMessage = messages.length > 0 ? messages[messages.length - 1] : null;

                if (maxMessage != null) {
                    element.children("div").html(recognizeUser(selfId, maxMessage.sender_id) +
                        truncateMessage(maxMessage.content));
                    if (chatId != currentChatId && maxMessage.timestamp > scope.checkpoint) {
                        setUnreadMessageState(element.children("div"));
                    }
                }
            }
        };

        return directive;
    })

    .directive('messageData', function () {
        var directive = {};
        directive.restrict = 'A';
        directive.scope = {
            detailMessages: "=",
            detailUsers: "=",
            scroll: "=",
            selfId: "@",
            switchChat: "="
        };

        directive.link = function (scope, element, attrs) {
            scope.$watchCollection('detailMessages', messageListener);
            // TODO: May add another listener on detailUsers if users can change on the fly.

            function messageListener(newModel, oldModel, scope) {
                var targetElement = element.find("#mainMessages");
                var selfId = scope.selfId;
                var detailMessages = scope.detailMessages;
                var detailUsers = scope.detailUsers;
                var scrollTopOrBottom = scope.scroll;
                var displayTimeRes = 120000;

                var templateHtmlForDateTime =
                    '<div class="meta__sub--light" style="text-align: center">@dateTime</div>';

                var templateHtmlForSelf =
                    '<div class="message--send">' +
                    '<figure class="message__avatar_send">' +
                    '   <img src="@imgURI" />' +
                    '</figure>' +
                    '<div class="message__bubble--send">@messageBody</div>' +
                    '</div>' +
                    '<div class="cf"></div>';
                var templateHtmlForOthers =
                    '<div class="message">' +
                    '<figure class="message__avatar">' +
                    '   <img src="@imgURI" />' +
                    '</figure>' +
                    '<div class="message__bubble">@messageBody</div>' +
                    '</div>' +
                    '<div class="cf"></div>';
                var whoseId = null;

                if (scope.switchChat) {
                    // 切换chatId，重新显示所有message
                    if (!!selfId) {
                        targetElement.empty();
                        for (var i = 0; i < detailMessages.length; i++) {
                            if (i == 0 || detailMessages[i].timestamp - detailMessages[i - 1].timestamp > displayTimeRes) {
                                targetElement.append(templateHtmlForDateTime.replace('@dateTime', displayDateTime(detailMessages[i].timestamp, false)));
                            }
                            whoseId = detailMessages[i].sender_id;
                            if (whoseId == selfId) {
                                targetElement.append(templateHtmlForSelf.replace('@messageBody', alterLinkContent(detailMessages[i].content, scrollTopOrBottom))
                                    .replace('@imgURI', detailUsers[selfId].pic));
                            } else {
                                targetElement.append(templateHtmlForOthers.replace('@messageBody', alterLinkContent(detailMessages[i].content, scrollTopOrBottom))
                                    .replace('@imgURI', (!!detailUsers[whoseId]) ? detailUsers[whoseId].pic : null));
                            }
                        }
                    }
                    scope.switchChat = false;
                } else {
                    if (!!selfId) {
                        if (scope.scroll == "bottom") {
                            for (var i = oldModel.length; i < newModel.length; i++) {
                                if (i != 0 && i == oldModel.length && newModel[i].timestamp - oldModel[oldModel.length - 1].timestamp > displayTimeRes ||
                                    i > oldModel.length && newModel[i].timestamp - newModel[i - 1].timestamp > displayTimeRes) {
                                    targetElement.append(templateHtmlForDateTime.replace('@dateTime', displayDateTime(newModel[i].timestamp, false)));
                                }
                                whoseId = newModel[i].sender_id;
                                if (whoseId == selfId) {
                                    targetElement.append(templateHtmlForSelf.replace('@messageBody', alterLinkContent(newModel[i].content, scrollTopOrBottom))
                                        .replace('@imgURI', detailUsers[selfId].pic));
                                } else {
                                    targetElement.append(templateHtmlForOthers.replace('@messageBody', alterLinkContent(newModel[i].content, scrollTopOrBottom))
                                        .replace('@imgURI', (!!detailUsers[whoseId]) ? detailUsers[whoseId].pic : null));
                                }
                            }
                        } else {
                            for (var i = newModel.length - oldModel.length - 1; i >= 0; i--) {
                                whoseId = newModel[i].sender_id;
                                if (whoseId == selfId) {
                                    targetElement.prepend(templateHtmlForSelf.replace('@messageBody', alterLinkContent(newModel[i].content, scrollTopOrBottom))
                                        .replace('@imgURI', detailUsers[selfId].pic));
                                } else {
                                    targetElement.prepend(templateHtmlForOthers.replace('@messageBody', alterLinkContent(newModel[i].content, scrollTopOrBottom))
                                        .replace('@imgURI', (!!detailUsers[whoseId]) ? detailUsers[whoseId].pic : null));
                                }
                                if (i == 0 || newModel[i].timestamp - newModel[i - 1].timestamp > displayTimeRes) {
                                    targetElement.prepend(templateHtmlForDateTime.replace('@dateTime', displayDateTime(newModel[i].timestamp, false)));
                                }
                            }
                        }
                    }
                }


                // scroll to bottom
                scroll(scrollTopOrBottom);
            }
        };

        return directive;
    })
;


function recognizeUser(senderId, selfId) {
    if (senderId != selfId) {
        return '';
    } else {
        return '[我] ';
    }
}

function truncateMessage(message) {
    if (!!message) {
        if (message.indexOf("http://") >= 0 || message.indexOf("https://") >= 0) {
            if (message.lastIndexOf(".png") >= 0 || message.lastIndexOf(".jpg") >= 0 || message.lastIndexOf(".bmp") >= 0) {
                return '[图片]';
            } else {
                return '[文件]';
            }
        } else {
            var strs = new Array();
            strs = message.split("<br>");

            if (strs[0].length >= 10 || message.indexOf("<br>") > 0) {
                return strs[0] + '...';
            } else {
                return strs[0];
            }
        }
    } else {
        return '';
    }
}

function alterLinkContent(content, scrollTopOrBottom) {
    if (content.indexOf("http://") >= 0 || content.indexOf("https://") >= 0) {
        if (content.lastIndexOf(".png") >= 0 || content.lastIndexOf(".jpg") >= 0 || content.lastIndexOf(".bmp") >= 0) {
            var id = content.match(/file_id=(.*)/i)[1];
            return '<img id="' + id + '" onclick="window.open(\'' + content + '\',\'_system\')" src="' + content + '" width="100%" onload="adjustHeightOnImageLoad(\'' + id + '\',\'' + scrollTopOrBottom + '\')">';
        } else {
            return '<a onclick="window.open(\'' + content + '\',\'_system\')">' + content + '</a>';
        }
    } else {
        return content;
    }
}

function setUnreadMessageState(element) {
    element.css('color', 'red');
    element.css('font-weight', 'bold');
}

function clearUnreadMessageState(element) {
    element.css('color', 'grey');
    element.css('font-weight', '');
}

function displayDateTime(timestamp, short) {
    if (timestamp == 0) return "";
    var currentDate = parseInt((new Date().getTime()) / 86400000);
    var dateInt = parseInt(timestamp / 86400000);
    var dateObj = new Date(timestamp);
    if (currentDate == dateInt) {
        return prependZero(dateObj.getHours()) + ':' + prependZero(dateObj.getMinutes());
    } else if (dateInt == currentDate - 1) {
        return '昨天' + prependZero(dateObj.getHours()) + ':' + prependZero(dateObj.getMinutes());
    } else {
        if (short) {
            return prependZero(parseInt(dateObj.getFullYear() % 100)) + '/' + prependZero(parseInt(dateObj.getMonth() + 1)) + '/' +
                prependZero(dateObj.getDate()) + ' ' + prependZero(dateObj.getHours()) + ':' + prependZero(dateObj.getMinutes());
        } else {
            return dateObj.getFullYear() + '年' + prependZero(parseInt(dateObj.getMonth() + 1)) + '月' + prependZero(dateObj.getDate()) +
                '日' + prependZero(dateObj.getHours()) + ':' + prependZero(dateObj.getMinutes());
        }
    }
}

function prependZero(n) {
    if (n < 10) {
        n = "0" + n;
    }
    return n;
}

function scroll(direction)
{
    if (direction == 'bottom') {
        jQuery("#message-list").scrollTop(jQuery("#message-list")[0].scrollHeight);
    } else {
        jQuery('#message-list').scrollTop(1);
    }
}

function adjustHeightOnImageLoad(image_id, direction)
{
    var img = document.getElementById(image_id);

    if (img.complete) {
        scroll(direction);
    } else {
        img.onload = function () {
            scroll(direction);
            img.onload = null;
        };
    };
}